An important aspect of the design and development of a computer program is debugging which is intended to locate and identify errors in a computer program under development. Typically, a programmer uses another computer program commonly known as a “debugger” to debug a program under development. Conventional debuggers typically support two primary operations to assist a computer programmer. A first operation supported by conventional debuggers is a step function which permits a computer programmer to process instructions, also known as statements, one at a time in a computer program and see the results of each instruction upon completion. While the step operation provides a programmer with a large amount of information about a program during its execution, stepping through hundreds or thousands of program instructions is tedious and time consuming. The programmer may be required to step through many program instructions that are already known to be error-free before a set of instructions to be analyzed are executed.
To address this difficulty, a second operation supported by conventional debuggers is the breakpoint operation which permits a computer programmer to identify a breakpoint as a precise instruction at which execution of a computer program is halted. As a computer program is executed by a debugger, the program executes in a normal fashion until a breakpoint is reached, the program stops execution and the debugger displays the results of the computer program to the programmer for analysis.
Step operations and breakpoints are typically used together to simplify the debugging process. Specifically, a user during a common debugging operation will set a breakpoint at the beginning of a desired set of instructions to be analyzed and then begin execution of the program undergoing debugging. Execution halts at a breakpoint and the programmer then steps through the desired set of instructions line-by-line using the step operation. Consequently, a programmer is able to quickly isolate and analyze a particular set of instructions without having to step through irrelevant portions of a computer program.
Most breakpoints supported by conventional debuggers are unconditional meaning that once such a breakpoint is reached, execution of the program is always halted. Some debuggers, however, also support the use of conditional breakpoints which only halt execution of a program when a variable used by the program is set to a predetermined value at the time such a breakpoint is reached. One significant drawback to conventional breakpoints results from the fact that some instructions in a computer program are executed fairly often for different purposes and may result in many needless stoppages before a desired stoppage is encountered. This problem is especially pronounced in object-oriented programming (OOP) and other highly modular languages where a single general purpose portion of a computer program may be executed in many different situations for different purposes.
With an object-oriented programming language, for example, a program is constructed from a number of “objects,” each of which includes data and/or one or more sets of instructions, often referred to as routines or methods that define specific operations that can be performed on the data. A large number of objects may be used to build a computer program with each object interacting with other objects in the computer program to perform desired operations. When one object invokes a particular routine in another object, the former object is often said to be calling the routine in the latter object. Some general purpose objects in a computer program may support basic operations, e.g., displaying information to a user, printing information on a printer, storing or retrieving information from a database, etc. Particularly, these generic type of objects are called by many different objects so that placing a conventional breakpoint in a routine of one of these common generic objects will result in hundreds of unwanted stoppages prior to occurrence of a desired stoppage. Thus, context sensitive breakpoints can be set in certain debuggers to retrieve the sequence of routines in the computer program that are called just prior to reaching the breakpoint, such as in U.S. Pat. No. 6,077,312 entitled “Apparatus, Program Product and Method of Debugging Utilizing a Context Sensitive Breakpoint” issued Jun. 20, 2000, commonly owned by the assignee and herein incorporated by reference in its entirety. Context sensitive breakpoints locate the specific calls in other objects that relate to the desired stoppage in a particular object. This eliminates the extremely time consuming and tedious task of setting each breakpoint and eliminates the risk that not all relevant calls are located so not all desired circumstances for inducing stoppages may be recognized during debugging.
But, setting breakpoints and halting execution of a program undergoing debugging is still onerous. Significant time is spent going through the breakpoints, whether the breakpoints are general or are context specific, as above. Merely watching breakpoints, moreover, does not solve the problem of determining the dynamics of an executing program in which variables and other expressions stored in a memory location may constantly change. These changing variables, moreover, may have either a direct or an indirect impact on other variables and other computer expressions.
As an example, if a user sets a breakpoint at line 12 in procedure A, she/he almost always sets a breakpoint at line 40 in some procedure B also because this is where some particular data she/he is interested in is processed. In fact, this occurrence is so common that one of the most popular features of debuggers today is to allow users to save their debug environment and restore it the next time they start debugging. While this is helpful to those users who start debugging one problem and have to stop and resume debugging later, it seldom helps the user to debug a similar problem the next time and the user must establish the same breakpoints and program variable monitors again. How a user got to a particular environment is not at all obvious; there may be different codes acting on different structures. Once a user sets breakpoints, moreover, the breakpoints must be managed meaningfully.
In addition, contemporary debuggers usually associate an environment instance with a specific program. While this works in some situations, it is of little help in others, especially where the same objects are called in other programs. Similarly, if a user would like to debug a specific process or job on a target machine, but doesn't know the program name on that machine, it may be difficult, if not impossible, to restore a debugging environment from the previous debug session.
There is thus a significant need in the industry to help programmers establish important breakpoint and monitor scenarios and to be able to recall these scenarios across different programs that are debugged.